﻿using System;
using System.IO;
using System.Web;
using System.Web.UI;
using EPiServer;

namespace TemplateFoundation.UserControls
{
    /// <summary>
    /// Used to render user controls to a string, for example when adding markup asynchronously through AJAX
    /// </summary>
    /// <typeparam name="T">The type of the user control</typeparam>
    /// <remarks>Uses a standard ASP.NET Page object to host the user control</remarks>
    public class UserControlRenderer<T> : UserControlRenderer<T, SimplePage> where T : UserControl, new()
    {
        public UserControlRenderer(string path) : base(path) { }
    }

    /// <summary>
    /// Used to render user controls to a string, for example when adding markup asynchronously through AJAX
    /// </summary>
    /// <typeparam name="TU">The type of the user control</typeparam>
    /// <typeparam name="TP">The type of page container to use for instantiating the user control</typeparam>
    public class UserControlRenderer<TU, TP> where TU : UserControl, new() where TP : Page, new()
    {
        /// <summary>
        /// Initializes a new object used to render a user control as a string
        /// </summary>
        /// <param name="path">The virtual path to the user control (.ascx) file</param>
        public UserControlRenderer(string path)
        {
            Page = new TP();

            UserControl = (TU)Page.LoadControl(path);
        }

        /// <summary>
        /// Gets the rendered user control's markup
        /// </summary>
        public override string ToString()
        {
            if (HttpContext.Current == null)
            {
                throw new NotSupportedException("No HTTP context available, user control cannot be rendered");
            }

            Page.Controls.Add(UserControl);

            var markup = new StringWriter();

            HttpContext.Current.Server.Execute(Page, markup, false);

            return markup.ToString();
        }

        public TU UserControl { get; set; }

        protected TP Page { get; set; }
    }

    /// <summary>
    /// Used to render user controls to a string, for example when adding markup asynchronously through AJAX
    /// </summary>
    /// <remarks>Uses a standard ASP.NET Page object to host the user control</remarks>
    public class UserControlRenderer : UserControlRenderer<EPiServer.UserControlBase, SimplePage>
    {
        public UserControlRenderer(string path) : base(path) { }
    }
}